import { Singleton, Mutex } from 'decorates';
import KeystoneService, { User } from './keystone.service';
import NetService, { FaceError } from './net.service';
import EventService from './event.service';

/**
 * 用户数据服务类
 * 提供用户信息的缓存及访问
 */
@Singleton()
export default class UserService {
  private netService = new NetService();

  private eventService = new EventService();

  private keystone = new KeystoneService();

  private current_: User = {
    name: '我',
    authorized: false,
    id: ''
  } as User;

  /**
   * 当前登陆用户
   */
  public get current () {
    return this.current_;
  }

  private users_: User[] = [];
  /**
   * 用户列表
   */
  public get users () {
    return this.users_;
  }

  /**
   * 用户列表字典
   */
  public usersMap: { [guid: string]: Any } = {};

  constructor () {
    // 用户
    // 设置插入回调
    this.netService?.on('sync.user.add', (add) => {
      if (!add || !add.body) {
        return;
      }
      this.setUserForList(add.body);
    });
    // 设置更新回调
    this.netService?.on('sync.user.update', (edit) => {
      if (!edit || !edit.body) {
        return;
      }
      this.setUserForList(edit.body);
    });
    // 设置删除回调
    this.netService?.on('sync.user.delete', (del) => {
      if (!del || !del.body) {
        return;
      }
      this.removeUserForList(del.body);
    });
  }

  public async load () {
    if (!this.keystone.load()) {
      throw new FaceError(401);
    }
    let user: User = this.keystone.user;
    // 缓存最长保存1小时
    // 缓存保存 24小时
    if (Date.now() - user.timestamp > 1000 * 60 * 60) {
      throw new FaceError(401);
    }
    this.current_ = user;
    // this.fetchUsers();
  }

  public async signin (username: string, password: string) {
    const { success, data, message } = await this.netService.send('user.signin', { username, password }, 'post');
    if (!success || !data || !data.token) {
      return message;
    }
    let user = { ...data };
    user.authorized = true;
    user.timestamp = Date.now();
    // 设置令牌
    this.keystone.token = data.token;
    this.keystone.user = user;
    this.keystone.store(user);
    return false;
  }

  public async signup (name: string, username: string, password: string, code: string) {
    const { message } = await this.netService.send('user.signup', { name, username, password, code }, 'post');
    return message;
  }

  @Mutex('fetchUsers')
  public async fetchUsers () {
    let { success, data } = await this.netService.send('user.all', {}, 'get');
    if (success && data && data.length > 0) {
      for (let user of data) {
        this.usersMap[user.id] = user;
        if (user.id === this.current.id) {
          user.local = true;
        } else {
          user.local = false;
        }
      }
      this.users_ = data;
    }
  }

  /**
   * 更新当前用户信息
   */
  public async updateUser (postData: Any) {
    const { success } = await this.netService.send('user.update', postData);
    if (success) {
      return Promise.resolve(success);
    }
  }

  /**
   * 将当前用户信息从缓存中删去
   * @param user 用户信息
   */
  public clearUser () {
    this.keystone.token = '';
    this.current_.authorized = false;
    this.current_.token = '';
    this.current_.timestamp = Date.now();
    this.keystone.remove('user');
    this.keystone.user = {} as User;
  }

  /**
     * 更新缓存的用户列表单个数据
     */
  private setUserForList (item: Any) {
    if (this.usersMap[item.id]) {
      for (let key in this.usersMap[item.id]) {
        this.usersMap[item.id][key] = item[key];
      }
    } else {
      this.users.push(item);
      this.usersMap[item.id] = item;
    }
  }

  /**
     * 删除缓存的用户列表单个数据
     */
  private removeUserForList (id: string) {
    if (this.usersMap[id]) {
      let index = this.users.indexOf(this.usersMap[id]);
      if (index > -1) {
        this.users.splice(index, 1);
        this.users_ = [...this.users];
      }
      delete this.usersMap[id];
    }
  }
}
